package com.web;

import com.service.Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

@Slf4j
@RestController
@RequestMapping("httpbin")
public class WebController {

    @Autowired
    Service service;


    @RequestMapping(value = "timeout", method = RequestMethod.POST)
    public String timeout(@RequestBody Map<String, String> flag) throws InterruptedException, ExecutionException {
        // mock the network request,
        log.info("param: {}", flag);
        if (flag.get("flag").equals("error")) {
            throw new RuntimeException("intending"); // throws excption as failure or success .
        }
        Long waittime = Long.valueOf(flag.get("wait-time"));
        return service.completableFuture(waittime).get();
    }
    // java.util.concurrent.CompletableFuture class com.service.Service.fallback(long,class java.lang.Throwable)



    @RequestMapping(value = "/circuitbreakerfallbackController2", method = RequestMethod.POST)
    public Mono<Map<String, String>> circuitbreakerfallbackController() {
        Map<String, String> map = new HashMap<String, String>() {
            {
                put("key", "val");
            }
        };
        return Mono.just(map);
    }

    @RequestMapping(value = "/circuitBreaker/delay/{integer}", method = RequestMethod.POST)
    public Mono<Map<String, String>> timeout(@PathVariable("integer") Integer integer) {
        log.info("wait {} seconds...", integer);
        Map<String, String> map = new HashMap<String, String>() {
            {
                put("key", "val");
            }
        };
        return Mono.just(map).delayElement(Duration.ofSeconds(integer));
    }

    @PostMapping("/rewrite")
    public Mono<Map<String, String>> rewrite(@RequestHeader Map<String, String> headers) {
        Map<String, String> map = new HashMap<String, String>() {
            {
                this.put("type", "rewrite");
            }
        };
        return Mono.just(map);
    }

    @RequestMapping("/get/map")
    public Mono<Map<String, String>> getMap() {
        Map<String, String> map = new HashMap<String, String>() {
            {
                put("key1", "val1");
            }
        };
        return Mono.just(map);
    }

    @RequestMapping("/get")
    public Mono<String> get(@RequestHeader Map<String, String> headers) {
        headers.entrySet().forEach(kv -> {
            String key = kv.getKey();
            String value = kv.getValue();
            log.info("key:{},val:{}", key, value);
        });
        return Mono.just("hcj");
    }

    Flux<Long> longFlux = Flux.interval(Duration.ofMillis(500)).take(10).onBackpressureBuffer(10);

    @RequestMapping("/get/list/interval")
    public Flux<String> getList() {
        String json = "{\"age\":%s}";
        return longFlux.map(l -> {
            return String.format(json, l);
        });
    }

//    @RequestMapping("/get/list/delay")
//    public Flux<String> getListWithDelay() {
//        Flux<Long> longFlux = Flux.interval(Duration.ofMillis(500)).take(10).onBackpressureBuffer(10);
//    }
}
